package cn.workreport.modules.role.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.workreport.modules.common.vo.PageVO;
import cn.workreport.modules.group.service.IGroupService;
import cn.workreport.modules.organization.entity.Organization;
import cn.workreport.modules.organization.service.IOrganizationService;
import cn.workreport.modules.role.entity.Role;
import cn.workreport.modules.role.mapper.RoleMapper;
import cn.workreport.modules.role.service.IRoleService;
import cn.workreport.modules.users.entity.UserEntity;
import cn.workreport.modules.users.service.IUserService;
import cn.workreport.util.InitData;
import cn.workreport.util.JsonResult;
import cn.workreport.util.UserChacheFromToken;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务接口实现类
 * </p>
 *
 * @author yyf
 * @since 2022-01-04
 */
@Slf4j
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    private InitData initData;

    @Autowired
    private IUserService userService;

    @Autowired
    private IOrganizationService organizationService;

    @Override
    public void wrapEntity(Role entity) {
        if (ObjectUtil.isEmpty(entity)) {
            return;
        }
        Organization org = organizationService.getById(entity.getOrgId());
        if (ObjectUtil.isNotEmpty(org)) {
            entity.setOrgName(org.getOrgName());
        }
    }

    @Override
    public PageVO<Role> pageEntity(IPage<Role> page, Wrapper<Role> queryWrapper) {
        IPage<Role> pageResult = this.page(page, queryWrapper);
//        pageResult.getRecords().forEach(this::wrapEntity);
        Set<Integer> orgIdSet = pageResult.getRecords().stream().map(Role::getOrgId).collect(Collectors.toSet());
        if (ObjectUtil.isNotEmpty(orgIdSet)) {
            List<Organization> orgList = organizationService.listByIds(orgIdSet);
            if (ObjectUtil.isNotEmpty(orgList)) {
                Map<Integer, String> orgMap = orgList.stream()
                        .collect(Collectors.toMap(Organization::getId, Organization::getOrgName, (last, next) -> next));
                log.info("orgMap ====>" + orgMap);
                pageResult.getRecords().forEach(item -> {
                    if (ObjectUtil.isNotEmpty(item.getOrgId())) {
                        item.setOrgName(orgMap.get(item.getOrgId()));
                    }
                });
            }
        }
        return new PageVO<>(pageResult);
    }

    @Override
    public Role getByIdEntity(Integer id) {
        if (ObjectUtils.isEmpty(id)) {
            return null;
        }
        Role entity = super.getById(id);
        this.wrapEntity(entity);
        return entity;
    }

    @Override
    public JsonResult<?> saveOrUpdateEntity(Role entity) {
        String roleName = entity.getRoleName();
        Integer orgId = entity.getOrgId();
        if (StrUtil.isBlank(roleName)) {
            return JsonResult.fail("参数 roleName 不能为空");
        }
        if (ObjectUtil.isEmpty(orgId)) {
            return JsonResult.fail("参数 orgId 不能为空");
        }
        // 去掉前后空格
        roleName = StrUtil.trim(roleName);
        entity.setRoleName(roleName);
        // 名称不能重复
        Role hasRole = getEntityByName(roleName, orgId);
        if (!ObjectUtils.isEmpty(hasRole)) {
            // 如果是新增
            if (ObjectUtils.isEmpty(entity.getId())) {
                return JsonResult.fail("该名称已经存在，不能重复创建");
            }
            // 如果是修改
            else if (!hasRole.getId().equals(entity.getId())) {
                return JsonResult.fail("该名称已经存在，请重新修改");
            }
        }
        boolean isSuccess = super.saveOrUpdate(entity);
        if (!isSuccess) {
            return JsonResult.fail("操作失败");
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> removeByIdEntity(Integer id) {
        UserEntity loginUser = UserChacheFromToken.getUser();

        // 不能删除初始化的角色
        Role roleEntity = this.getById(id);
        if (ObjectUtil.isEmpty(roleEntity)) {
            return JsonResult.fail("该角色不存在");
        }
        for (InitData.InitRoleNameEnum roleNameEnum : InitData.InitRoleNameEnum.values()) {
            if (roleNameEnum.getRoleName().equals(roleEntity.getRoleName())) {
                return JsonResult.fail("该角色为初始化角色，不可删除");
            }
        }

        // 把绑定该角色的人置为普通角色
        List<UserEntity> userEntities = this.userService.listByRoleId(id);
        if (ObjectUtil.isNotEmpty(userEntities)) {
            Role narmalRole = getEntityByName(InitData.InitRoleNameEnum.NORMAL_ROLE.getRoleName(), loginUser.getOrgId());
            if (ObjectUtil.isEmpty(narmalRole)) {
                return JsonResult.fail("删除失败，初始化普通用户角色不存在");
            }
            for (UserEntity userEntity : userEntities) {
                userEntity.setRoleId(narmalRole.getId());
            }
            if (!this.userService.updateBatchById(userEntities)) {
                return JsonResult.fail("重置用户角色失败");
            }
        }

        // 执行删除角色
        if (!this.removeById(id)) {
            return JsonResult.fail();
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> removeByIdsEntity(List<Integer> ids) {
        for (Integer id : ids) {
            JsonResult<?> jsonResult = removeByIdEntity(id);
            if (!jsonResult.getState().equals(JsonResult.SUCCESS)) {
                return JsonResult.fail();
            }
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> toggleUse(Integer id, Boolean asUse) {
        Role role = super.getById(id);
        if (ObjectUtils.isEmpty(role)) {
            return JsonResult.fail("该条数据不存在");
        }
        role.setAsUse(asUse);
        boolean isSuccess = super.saveOrUpdate(role);
        if (!isSuccess) {
            return JsonResult.fail();
        }
        return JsonResult.ok();
    }

    @Override
    public Role getEntityByName(String roleName, Integer orgId) {
        if (StrUtil.isBlank(roleName) || ObjectUtil.isEmpty(orgId)) {
            return null;
        }
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getRoleName, roleName);
        wrapper.eq(Role::getOrgId, orgId);
        return getOne(wrapper);
    }

    @Override
    public List<Role> getEnableList(Integer orgId) {
        if (ObjectUtil.isEmpty(orgId)) {
            return null;
        }
        LambdaQueryWrapper<Role> wrapper = Wrappers.<Role>lambdaQuery();
        wrapper.eq(Role::getAsUse, true);
        wrapper.eq(Role::getOrgId, orgId);
        wrapper.orderByDesc(Role::getCreatedTime);
        return super.list(wrapper);
    }

    @Override
    public List<String> listInitRoleName() {
        List<String> roleNameList = new ArrayList<>();
        for (InitData.InitRoleNameEnum roleNameEnum : InitData.InitRoleNameEnum.values()) {
            roleNameList.add(roleNameEnum.getRoleName());
        }
        return roleNameList;
    }

    @Override
    public List<Role> listByOrgId(Integer orgId) {
        if (ObjectUtil.isEmpty(orgId)) {
            return null;
        }
        LambdaQueryWrapper<Role> queryWrapper = Wrappers.<Role>lambdaQuery();
        queryWrapper.eq(Role::getOrgId, orgId);
        queryWrapper.orderByDesc(Role::getCreatedTime);
        return this.list(queryWrapper);
    }

}

